﻿namespace Cuce.ReportingServices
{
    using System.Collections.ObjectModel;
    using System;
    using System.IO;

    /// <summary>
    /// This class represents a collection of Rows
    /// </summary>
    public class ReportOutputRowCollection : Collection<ReportOutputRow>
    {

        /// <summary>
        /// Converts the specified report data.
        /// </summary>
        /// <param name="reportData">The report data.</param>
        /// <param name="outputType">Type of the output.</param>
        /// <returns></returns>
        public static ReportOutputRowCollection Convert(byte[] reportData, OutputType outputType)
        {
            var i = new ReportOutputRowCollection();

            foreach (var line in ConvertData(reportData, outputType))
            {
                i.Add(new ReportOutputRow(new ReportOutputColumnCollection(line, outputType)));
            }

            return i;


        }



        /// <summary>
        /// Converts the data.
        /// </summary>
        /// <param name="results">The results.</param>
        /// <param name="outputType">Type of the output.</param>
        /// <returns></returns>
        private static Collection<string> ConvertData(byte[] results, OutputType outputType)
        {


           var result = new Collection<string>();

            string filename = SaveFile(results,outputType );

            //convert text file to string collection
            using (StreamReader SR = File.OpenText(filename))
            {

                string S = SR.ReadLine();
                while (S != null)
                {
                    result.Add(S);
                    S = SR.ReadLine();
                }
                SR.Close();
            }


            File.Delete(filename);

            return result;


        }


        /// <summary>
        /// Saves the file.
        /// </summary>
        /// <param name="results">The results.</param>
        /// <param name="outputType">Type of the output.</param>
        /// <returns></returns>
        private static string SaveFile(byte[] results, OutputType outputType)
        {
            //convert to string
            String PersonalFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            string filename = PersonalFolder + "\\unitTest" + (new Random().Next() * 10).ToString().Replace("-", "") + "." + outputType.ToString();

            using (FileStream fs = File.Create(filename))
            {
                var bw = new BinaryWriter(fs);
                bw.Write(results);
                bw.Close();
            }

            return filename;
        }

        /// <summary>
        /// Returns the collection of strings, each row seperated by a newline char
        /// </summary>
        /// <returns>String of results</returns>
        public override string ToString()
        {
            string result = "";

            foreach (ReportOutputRow value in this)
            {
                result = result + value.ToString() + "\n";
            }

            return result;
        }

    }

    /// <summary>
    /// This class represents a Output Column
    /// </summary>
    public class ReportOutputColumn
    {
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="newValue">string to add to column</param>
        public ReportOutputColumn(string newValue)
        {
            Value = newValue;
        }

        private string Value { get; set; }

        /// <summary>
        /// Returns a string representation of the value
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return this.Value.ToString();
        }

       
    }

    /// <summary>
    /// This class represents a collection of Columns
    /// </summary>
    public class ReportOutputColumnCollection : Collection<ReportOutputColumn>
    {
        /// <summary>
        /// Returns a string that represents all the data in a row
        /// </summary>
        /// <returns>String that represents all the data in a row</returns>
        public override string ToString()
        {
            string result = "";

            foreach (var value in this)
            {
                if (result != "")
                    result = result + "," + value.ToString();
                else
                    result = value.ToString();
            }

            return result;
        }


        /// <summary>
        /// Initializes a new instance of the <see cref="ReportOutputColumnCollection"/> class.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="outputType">Type of the output.</param>
        public ReportOutputColumnCollection(string value, OutputType outputType)
        {
            if (outputType == OutputType.CSV)
                this.Convert(value, ",");
            //else if (outputType == OutputType.XML)
            //    this.Convert(value, "><");
            //else if (outputType == OutputType.HTML4)
            //    this.Convert(value, "<td>");
           

        }


        /// <summary>
        /// Reports the output column collection.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="splitChar">The split char.</param>
        public void Convert(string value, string splitChar)
        {

            string[] list = value.Split(splitChar.ToCharArray());

            foreach (var i in list)
            {
                this.Add(new ReportOutputColumn(i));
            }

        }
    }

    /// <summary>
    /// This class represents a Row
    /// </summary>
    public class ReportOutputRow
    {

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="value">Collection of Columns</param>
        public ReportOutputRow(ReportOutputColumnCollection value)
        {
            this.Columns = value;
        }

        /// <summary>
        /// Gets or sets the Actual columns
        /// </summary>
        public ReportOutputColumnCollection Columns { get; set; }

        /// <summary>
        /// Returns string representation of all Columns
        /// </summary>
        /// <returns>A string of all the columns</returns>
        public override string ToString()
        {
            return Columns.ToString();
        }

    }


}
